package com.chiyou.service;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpException;

import com.alibaba.fastjson.JSONArray;
import com.chiyou.common.indicator.DMI;
import com.chiyou.common.indicator.KDJ;
import com.chiyou.common.indicator.KLineData;
import com.chiyou.common.models.HisData;
import com.chiyou.common.utils.PropertiesUtils;
import com.chiyou.common.utils.RedisUtilStr;
import com.chiyou.common.utils.RedisUtils;
import com.okcoin.rest.future.IFutureRestApi;
import com.okcoin.rest.future.impl.FutureRestApiV1;
import com.okcoin.rest.future.models.OkcoinOrder;
import com.okcoin.rest.future.models.Orders;

public class FutureNo1MonitorService implements Runnable {
public static RedisUtilStr redisUtilStr = new RedisUtilStr();
static{
	String current_tard_price = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("current_tard_price");
	String option_status = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("option_status");
	String current_order_id = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("current_order_id");
	String netwok_val = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("netwok_val");
	String tard_type = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("tard_type");
	
	redisUtilStr.set("netwok_val", netwok_val,0);
	redisUtilStr.set("current_tard_price", current_tard_price,0);
	redisUtilStr.set("option_status", option_status,0);
	redisUtilStr.set("current_order_id", current_order_id,0);
	redisUtilStr.set("tard_type", tard_type,0);
}
	public void run() {
		
		
		try {
			String api_key = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/conf.properties").getProperty("apikey");
			String secret_key = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/conf.properties").getProperty("secretkey");
			String url_prex = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/conf.properties").getProperty("urlprex");
			
			
			
			String tard_type = ""+ redisUtilStr.get("tard_type");
			String netwok_val = ""+ redisUtilStr.get("netwok_val");
			String current_tard_price = ""+ redisUtilStr.get("current_tard_price");
			String option_status = ""+ redisUtilStr.get("option_status");
			String current_order_id = ""+ redisUtilStr.get("current_order_id");

			/**
			 * get请求无需发送身份认证,通常用于获取行情，市场深度等公共信息
			 */
			IFutureRestApi futureGetV1 = new FutureRestApiV1(url_prex);

			/**
			 * post请求需发送身份认证，获取用户个人相关信息时，需要指定api_key,与secret_key并与参数进行签名，
			 * 此处对构造方法传入api_key与secret_key,在请求用户相关方法时则无需再传入，
			 * 发送post请求之前，程序会做自动加密，生成签名。
			 * 
			 */
			IFutureRestApi futurePostV1 = new FutureRestApiV1(url_prex, api_key, secret_key);

			this.doMonitor(futureGetV1, futurePostV1);

//			System.out.println("tard_type:" + RedisUtils.getObject("tard_type"));
//			System.out.println("netwok_val:" + RedisUtils.getObject("netwok_val"));
//			System.out.println("current_tard_price:" + RedisUtils.getObject("current_tard_price"));
//			System.out.println("option_status:" + RedisUtils.getObject("option_status"));
//			System.out.println("current_order_id:" + RedisUtils.getObject("current_order_id"));

//			writeTradeConf();
			// // 期货行情信息
			// String tickers = futureGetV1.future_ticker("btc_usd",
			// "this_week");
			// List<KLineData> kLineDatas = JSONArrayToKLineData(tickers);
			// KDJ kdj = new KDJ();
			// DMI dmi = new DMI();
			//
			// kdj.setM_kDatas(KLineDataToHisData(kLineDatas));
			// kdj.Calculate();
			// System.out.println(kdj.isBuyOrSell());
			// dmi.setM_kDatas(KLineDataToHisData(kLineDatas));
			// dmi.Calculate();
			// dmi.getIndicators();
			// System.out.println(dmi.isBuyOrSell());
			//
			// // 期货交易信息
			// String str3 = futureGetV1.future_trades("btc_usd", "this_week");
			// System.out.println(str3);
			// // 期货市场深度
			// String str2 = futureGetV1.future_depth("btc_usd", "this_week");
			// System.out.println(str2);
			//
			// // 期货账户信息
			// String userInfo = futurePostV1.future_userinfo();
			// System.out.println(userInfo);
			//
			// // 期货用户持仓查询
			// String position = futurePostV1.future_position("btc_usd",
			// "this_week");
			// System.out.println(position);

//			System.out.println("end......");
		} catch (Exception e) {
			String current_tard_price = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("current_tard_price");
			String option_status = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("option_status");
			String current_order_id = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("current_order_id");
			String netwok_val = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("netwok_val");
			String tard_type = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("tard_type");
			
			redisUtilStr.set("netwok_val", netwok_val,0);
			redisUtilStr.set("current_tard_price", current_tard_price,0);
			redisUtilStr.set("option_status", option_status,0);
			redisUtilStr.set("current_order_id", current_order_id,0);
			redisUtilStr.set("tard_type", tard_type,0);
			
			e.printStackTrace();
		}
	}

	// 1 kdj+dim 指标健康 判断是否开仓 平仓
	// 2 订单监控判断是否有未完订单 并修改上一次价格 超过10分钟应该取消订单

	private boolean doMonitor(IFutureRestApi futureGetV1, IFutureRestApi futurePostV1) throws HttpException, IOException, NumberFormatException, ParseException {
		String kline = futureGetV1.future_kline("btc_usd", "quarter", "1day", 0, 0);
//		String kline = futureGetV1.future_kline("btc_usd", "quarter", "1min", 0, 0);
		List<KLineData> kLineDatas = JSONArrayToKLineData(kline);
		KDJ kdj = new KDJ();
		DMI dmi = new DMI();

		kdj.setM_kDatas(KLineDataToHisData(kLineDatas));
		kdj.Calculate();
		dmi.setM_kDatas(KLineDataToHisData(kLineDatas));
		dmi.Calculate();
		dmi.isBuyOrSell();
		kdj.isBuyOrSell();
		OkcoinOrder okcoinOrder = getOrder(futurePostV1,"-1", "1", "1", "50");

		if (redisUtilStr.get("tard_type").equals("0") || redisUtilStr.get("tard_type").equals("1")) {
			OkcoinOrder order = getOrder(futurePostV1, "-1", "2", "1", "50");
			List<Orders> orderList = order.getOrders();
			
			if(orderList.size()>0){
				Orders obj = orderList.get(0);
				redisUtilStr.set("current_tard_price", obj.getPrice(),0);
				redisUtilStr.set("current_order_id", obj.getOrder_id(),0);
			}
		}
		

		if (okcoinOrder.getOrders().size() > 0) {

			redisUtilStr.set("option_status", 0,0);
			List<Orders> orderList = okcoinOrder.getOrders();
			for (int i = 0; i < orderList.size(); i++) {
				Orders order = orderList.get(i);
				//订单超过5分钟取消订单
				if ((System.currentTimeMillis() - Long.parseLong(order.getCreate_date())) / 1000 / 60 > 5) {
					futurePostV1.future_cancel("btc_usd", "quarter", order.getOrder_id());
				}
			}
		} else {
		
			if (kdj.isBuyOrSell() == 1 && dmi.isBuyOrSell() == 1) {
				System.out.println("开始做多");
				// 0:做多 1:做空 2:清仓
				redisUtilStr.set("tard_type", 0,0);
				redisUtilStr.set("option_status", 2,0);
			}

			if (kdj.isBuyOrSell() == 0 && dmi.isBuyOrSell() == 10) {
				System.out.println("启动做多网格。。。");
				// 0:做多 1:做空 2:清仓
				redisUtilStr.set("tard_type", 0,0);
				redisUtilStr.set("option_status", 1,0);
			}

			if (kdj.isBuyOrSell() == 0 && dmi.isBuyOrSell() == -10) {
				System.out.println("启动做空网格。。。");
				redisUtilStr.set("tard_type", 1,0);
				redisUtilStr.set("option_status", 1,0);
			}

			if (kdj.isBuyOrSell() == -1 && dmi.isBuyOrSell() == -1) {
				// 开始做空
				redisUtilStr.set("tard_type", 1,0);
				redisUtilStr.set("option_status", 2,0);
			}
		}
		
		
		return false;
	}

	private void writeTradeConf() {
		PropertiesUtils.setFileName(System.getProperty("user.dir") + "/conf/conf.properties");
		PropertiesUtils.setProperty("tard_type", RedisUtils.getObject("tard_type"));
		PropertiesUtils.setProperty("netwok_val", RedisUtils.getObject("netwok_val"));
		PropertiesUtils.setProperty("current_tard_price", RedisUtils.getObject("current_tard_price"));
		PropertiesUtils.setProperty("option_status", RedisUtils.getObject("option_status"));
		PropertiesUtils.setProperty("current_order_id", RedisUtils.getObject("current_order_id"));
	}

	private static List<KLineData> JSONArrayToKLineData(String klineJosn) {
		JSONArray klineArray = JSONArray.parseArray(klineJosn);

		List<KLineData> klines = new ArrayList<KLineData>();
		for (Object obj : klineArray) {
			JSONArray row = (JSONArray) obj;
			KLineData kline = new KLineData();
			kline.setDate(row.getLongValue(0));
			kline.setOpenPrice(row.getFloatValue(1));
			kline.setHighPrice(row.getFloatValue(2));
			kline.setLowPrice(row.getFloatValue(3));
			kline.setClosePrice(row.getFloatValue(4));
			kline.setTotalAmount(row.getLongValue(5));
			klines.add(kline);
		}

		return klines;
	}

	private static List<HisData> KLineDataToHisData(List<KLineData> klines) {

		List<HisData> hisDatas = new ArrayList<HisData>();
		for (KLineData obj : klines) {
			HisData hisData = new HisData();
			hisData.setOPEN(obj.getOpenPrice());
			hisData.setCLOSE(obj.getClosePrice());
			hisData.setHIGH(obj.getHighPrice());
			hisData.setLOW(obj.getLowPrice());
			hisData.setTIME(new Date(obj.getDate()));
			hisDatas.add(hisData);
		}

		return hisDatas;
	}
	
	
	public static String long2String(long longTime, String dataFormat) {
		Date d = new Date(longTime);
		SimpleDateFormat s = new SimpleDateFormat(dataFormat);
		String str = s.format(d);
		return str;
	}

	private OkcoinOrder getOrder(IFutureRestApi futurePostV1,String orderId, String status, String currentPage, String pageLength ) throws HttpException, IOException {
		String okCoinOrder = futurePostV1.future_order_info("btc_usd", "quarter",orderId, status,currentPage,pageLength);//"-1", "1", "1", "50");
		List<Orders> os = (List<Orders>) net.sf.json.JSONArray.toList(net.sf.json.JSONObject.fromObject(okCoinOrder).getJSONArray("orders"), Orders.class);
		OkcoinOrder orders = new OkcoinOrder();
		orders.setOrders(os);
		orders.setResult(net.sf.json.JSONObject.fromObject(okCoinOrder).getBoolean("result"));
		return orders;
	}

	public static void main(String[] args) {
		FutureNo1MonitorService futureNo1MonitorService = new FutureNo1MonitorService();

		ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

		service.scheduleAtFixedRate(futureNo1MonitorService, 0, 1, TimeUnit.SECONDS);
	}

	public static Date LongToDare(long str) throws ParseException {
		return new Date(str * 1000);
	}
}
